<!-- 发布、编辑新闻页面 -->

<script setup lang="ts">
import { ref, shallowRef, onBeforeUnmount, nextTick, onMounted, watch } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import type { NewsEditForm } from '@/types/news'
import '@wangeditor/editor/dist/css/style.css'
import service from '@/utils/axios'
import { stringToApiResponse } from '@/types/apiResponse'
import { IEditorConfig } from '@wangeditor/editor'
import { useLoginStore } from '@/stores/useLoginStore'

const router = useRouter()
const route = useRoute()
const loginStore = useLoginStore()

// 新闻ID。如果是编辑新闻，则代表被编辑的新闻ID；如果是发布新闻，则为新的新闻的ID
const newsId = ref()

// 编辑器实例，必须用 shallowRef
const editorRef = shallowRef()

// 提示信息
const doPrompt = (message: string) => {
  ElMessage.warning({
    message: message,
    appendTo: '#top-nav'
  })
}

// 表单数据
const form = ref<NewsEditForm>({
  title: '',
  sortId: 0,
  sortLabel: '',
  cover: '',
  summary: '',
  content: '',
  issues: [] as string[]
})

// 表单校验规则
const rules = {
  title: [
    { required: true, message: '请输入文章标题', trigger: 'blur' },
    { min: 2, max: 100, message: '标题长度在2-100个字符之间', trigger: 'blur' }
  ],
  sortId: [{ required: true, message: '请选择文章分类', trigger: 'change' }],
  content: [{ required: true, message: '请输入文章内容', trigger: 'blur' }]
}

const toolbarConfig = {}

// 编辑器配置
const editorConfig: Partial<IEditorConfig> = {
  placeholder: '请输入内容...',
  MENU_CONF: {}
}

interface NewsSort {
  id: number
  label: string
}

// 新闻分类（从后端获取）
const sorts = ref<NewsSort[]>([{
  id: 0,
  label: '',
}
])

// 加载新闻分类接口
const loadNewsSorts = async () => {
  const response = await service.get<string>('/news/getSorts')

  return stringToApiResponse(response.data);
}

// 加载话题接口
const loadIssues = async () => {
  const response = await service.get<string>('/issue/getAllIssues')

  return stringToApiResponse(response.data);
}

// 加载新闻编辑信息接口
const loadNewsEditInfo = async (newsId: number) => {
  const response = await service.get<string>(`/news/getNewsEditForm?newsId=${newsId}`)

  return stringToApiResponse(response.data);
}

// 保存并发布新闻接口
const saveAndPublishNews = async (form: NewsEditForm, newsId?: number) => {
  // 根据是否传递newsId判断是发布新闻还是编辑新闻
  if (newsId) {
    const response = await service.post<string>(`/news/publishNews?newsId=${newsId}`, form)
    return stringToApiResponse(response.data);
  } else {
    const response = await service.post<string>('/news/publishNews', form)
    return stringToApiResponse(response.data);
  }
}

// 添加话题接口
const addIssue = async (issue: string) => {
  const response = await service.get<string>(`/issue/addIssue?issueName=${issue}`)
  return stringToApiResponse(response.data);
}

// 话题（从后端获取）
const issues = ref([{
  id: 0,
  label: '',
}
])

// 话题输入相关
const inputVisible = ref(false)
const inputValue = ref('')
const InputRef = ref()

// 显示输入框
const showInput = () => {
  inputVisible.value = true
  nextTick(() => {
    InputRef.value.focus()
  })
}

// 添加话题标签时的方法
const handleInputConfirm = async () => {
  console.log('inputValue', inputValue.value);
  if (inputValue.value) {
    // 若输入的话题不为空
    if (form.value.issues.includes(inputValue.value)) {
      // 若输入的话题已存在
      doPrompt('话题已存在，请不要重复添加')
      inputVisible.value = false
      inputValue.value = ''
    } else {
      // console.log('添加话题', inputValue.value);
      // 调用后端接口在话题表中添加话题
      await addIssue(inputValue.value)

      form.value.issues.push(inputValue.value)
    }
    inputVisible.value = false
    inputValue.value = ''

  }
}

// 删除话题标签
const handleClose = (tag: string) => {
  form.value.issues = form.value.issues.filter((t: string) => t !== tag)
}

// 上传封面
const handleCoverSuccess = (response: any) => {

  form.value.cover = response.url
}

// 编辑器回调函数
const handleCreated = (editor: any) => {
  console.log('创建编辑器实例', editor);

  editorRef.value = editor // 记录 editor 实例
}

const formRef = ref()

// 保存文章
const handleSave = async () => {
  try {
    // 表单校验
    await formRef.value.validate()

    // 设置文章内容
    form.value.content = editorRef.value.getHtml()

    console.log(form.value);

    // 定义编辑或者发布后的新闻的ID
    const afterNewsId = ref(0);

    console.log('form.value.sortId',form.value.sortId);

    const response = await saveAndPublishNews(form.value, newsId.value)
    if (response.code === 200) {
      afterNewsId.value = response.data;
      ElMessage.success(response.message)
      await new Promise((resolve) => setTimeout(resolve, 1000));
      // 跳转到编辑或发布后的新闻页面
      router.push(`/newsArticle/${afterNewsId.value}`)
    } else if (response.code === 401) {
      ElMessage.warning('请先登录')
      loginStore.openLoginDialog();
      return
    }

    return;
  } catch (error) {
    if (error === false) {
      ElMessage.warning('请完善文章信息')
      return
    }
    console.error('保存失败:', error)
    ElMessage.error('保存失败')
  }
}

// 取消编辑
const handleCancel = () => {
  router.back()
}

// 组件销毁时，也及时销毁编辑器
onBeforeUnmount(() => {
  const editor = editorRef.value
  if (editor == null) return
  editor.destroy()
})

// 搜索建议
const querySearch = (queryString: string, cb: (arg: any[]) => void) => {
  const results = queryString
    ? issues.value.filter((issue: { label: string; id: number }) => {
      return issue.label.toLowerCase().includes(queryString.toLowerCase())
    })
    : issues.value
  cb(results)
}

// 选择建议
const handleSelect = (item: any) => {
  inputValue.value = item.label
  handleInputConfirm()
}

// 获取文章详情
const getArticleDetail = async (id: string) => {
  try {
    // 获取待编辑的新闻ID
    newsId.value = Number(id)
    const newsResponse = await loadNewsEditInfo(newsId.value);
    if (newsResponse.code === 200) {
      form.value = newsResponse.data.form;
      console.log('form.value.sortId', form.value.sortId);
      console.log('sorts', sorts.value);
      form.value.sortLabel = sorts.value.find(sort => sort.id === form.value.sortId)?.label;
      console.log('sortLabel', form.value.sortLabel);
      
    } else if (newsResponse.code === 404) {
      ElMessage.error('文章不存在')
      await new Promise((resolve) => setTimeout(resolve, 1000));
      return
    } else if (newsResponse.code === 403) {
      ElMessage.error('没有访问权限')
      await new Promise((resolve) => setTimeout(resolve, 1000));
      router.back()
      return
    } else if (newsResponse.code === 401) {
      ElMessage.warning('请先登录')
      loginStore.openLoginDialog();
      return
    }

  } catch (error) {
    console.error('获取文章详情失败:', error)
    ElMessage.error('获取文章详情失败')
  }
}

// 组件挂载时检查是否有query参数，若有说明是编辑新闻，加载待编辑的数据
onMounted(async () => {
  const newsId = route.query.id

  // 加载新闻分类
  const sortResponse = await loadNewsSorts();
  if (sortResponse.code === 200) {
    sorts.value = sortResponse.data.newsSorts;
  }
  // 加载话题
  const issuesResponse = await loadIssues();
  if (issuesResponse.code === 200) {
    issues.value = issuesResponse.data.issues;
  }

  // 必须在加载完分类后再加载编辑信息
  if (newsId) {
    getArticleDetail(newsId as string)
  } else {
    // 发布新闻，让新闻分类字段置空
    form.value.sortId = sorts.value[0].id;
    form.value.sortLabel = sorts.value[0].label;
    
  }
})

// 当路由参数变化时，重新加载页面
watch(() => route.query.id, () => {
  window.location.reload();
})

const handleSelect2 = (value: any) => {
  console.log('value', value);
}
</script>

<template>
  <div class="max-w-[1000px] mx-auto py-8 px-4">
    <div class="bg-white rounded-lg">
      <!-- 页面标题 -->
      <div class="p-6 border-b">
        <h1 class="text-2xl font-bold">
          {{ route.query.id ? '编辑新闻' : '发布新闻' }}
        </h1>
      </div>

      <!-- 表单内容 -->
      <div class="p-6">
        <el-form ref="formRef" :model="form" :rules="rules" label-width="100px" class="space-y-6">
          <!-- 标题 -->
          <el-form-item label="新闻标题" prop="title" required>
            <el-input v-model="form.title" placeholder="请输入新闻标题" maxlength="100" show-word-limit />
          </el-form-item>

          <!-- 分类 -->
          <el-form-item label="所属分类" prop="sortId" required>
            <el-select v-model="form.sortId" placeholder="请选择新闻分类" @change="handleSelect2">
              <el-option v-for="item in sorts" :key="item.id" :label="item.label" :value="item.id" />
            </el-select>
          </el-form-item>

          <!-- 话题 -->
          <el-form-item label="添加话题">
            <el-tag v-for="tag in form.issues" :key="tag" class="mr-2 my-1" closable @close="handleClose(tag)">
              {{ tag }}
            </el-tag>
            <el-autocomplete v-if="inputVisible" ref="InputRef" v-model="inputValue" class="ml-1" style="width: 150px"
              size="small" :fetch-suggestions="querySearch" value-key="label" @select="handleSelect"
              @keyup.enter="handleInputConfirm" @blur="handleInputConfirm" placeholder="创建新话题" />
            <el-button v-else class="button-new-tag ml-1" size="small" @click="showInput">
              + 新话题
            </el-button>
          </el-form-item>

          <!-- 封面 -->
          <el-form-item label="新闻封面">
            <div class="flex items-center gap-4">
              <!-- 将action设置为上传功能的后端接口地址（包含前缀） -->
              <el-upload class="cover-uploader" action="" :show-file-list="false" :on-success="handleCoverSuccess">
                <div v-if="form.cover"
                  class="w-[200px] h-[140px] border border-dashed border-gray-300 rounded-lg overflow-hidden">
                  <img :src="form.cover" class="w-full h-full object-cover" />
                </div>
                <div v-else
                  class="w-[200px] h-[140px] border border-dashed border-gray-300 rounded-lg flex flex-col items-center justify-center cursor-pointer hover:border-primary">
                  <el-icon class="text-3xl text-gray-400">
                    <Plus />
                  </el-icon>
                  <span class="mt-2 text-gray-500">上传封面</span>
                </div>
              </el-upload>
              <div class="text-gray-500 text-sm">
                建议尺寸：800x600px，支持 jpg、png 格式
              </div>
            </div>
          </el-form-item>

          <!-- 摘要 -->
          <el-form-item label="新闻摘要">
            <el-input v-model="form.summary" type="textarea" :rows="3" resize="none" placeholder="请输入新闻摘要"
              maxlength="200" show-word-limit />
          </el-form-item>

          <!-- 内容 -->
          <el-form-item label="主体内容" prop="content" required>
            <div class="border rounded-lg">
              <Toolbar class="fixed-toolbar" style="border-bottom: 1px solid #ccc" :editor="editorRef"
                :defaultConfig="toolbarConfig" mode="default" />
              <Editor class="fixed-toolbar" style="height: 500px" v-model="form.content" :defaultConfig="editorConfig"
                mode="default" @onCreated="handleCreated" />
            </div>
          </el-form-item>
        </el-form>

        <!-- 操作按钮 -->
        <div class="flex justify-end gap-4 mt-8">
          <el-button @click="handleCancel">取消</el-button>
          <el-button type="primary" @click="handleSave">
            保存新闻
          </el-button>
        </div>
      </div>
    </div>
  </div>
</template>

<style lang="less" scoped>
.cover-uploader {
  :deep(.el-upload) {
    border: 1px dashed var(--el-border-color);
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
    transition: var(--el-transition-duration-fast);

    &:hover {
      border-color: var(--el-color-primary);
    }
  }
}

.el-button--primary {
  --el-button-bg-color: #056de8;
  --el-button-border-color: #056de8;
  --el-button-hover-bg-color: #0461cf;
  --el-button-hover-border-color: #0461cf;
}

.fixed-toolbar {
  max-width: 820px;
}
</style>
